home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Portable Patmos 1.1 / patmos-src / src / console.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-19  |  13.1 KB  |  579 lines  |  [TEXT/KAHL]

  1. /*******************************************************************\
  2. * Console driver based on    
  3. *    the sample application from Inside Macintosh (RoadMap p.15-17)
  4. *
  5. \*******************************************************************/
  6.  
  7. #include <Desk.h>
  8. #include <Scrap.h>
  9. #include <Fonts.h>
  10. #include <Memory.h>
  11. #include <OSEvents.h>
  12. #include <ToolUtils.h>
  13. #include <SegLoad.h>
  14. #include <Windows.h>
  15. #include <Dialogs.h>
  16. #include <Events.h>
  17. #include <Menus.h>
  18. #include <TextEdit.h>
  19. #include <AppleEvents.h>
  20.  
  21. #define appleID            128
  22. #define fileID            129
  23. #define editID            130
  24.  
  25. /* Edit menu command indices */
  26. #define undoCommand     1
  27. #define cutCommand        3
  28. #define copyCommand        4
  29. #define pasteCommand    5
  30. #define clearCommand    6
  31. #define selallCommand   7
  32.  
  33. /* Menu indices */
  34. #define appleM            0
  35. #define fileM            1
  36. #define editM            2
  37.  
  38. #define SBarWidth    15
  39.  
  40. int DoCommand(long mResult);
  41.  
  42. #include "crtlocal.h"
  43.  
  44. typedef struct
  45.     {
  46.     long    readptr,writeptr,complete_line;
  47.     char    buffer[8192];
  48.     } tty_struct;
  49.  
  50. static struct crt_win {
  51.  WindowRecord    crt_wRecord;
  52.  int            linesInFolder;
  53.  ControlHandle     vScroll;
  54.  TEHandle        crt_TEH;
  55.  WindowPtr        crt_myWindow;
  56.  tty_struct        *console;
  57. } crt_windows[10],*w;
  58.  
  59. void __exit(int status)
  60.     {
  61.     closeall();
  62.     sock_close_all();
  63.     if (w && w->crt_myWindow)
  64.         {
  65.         TESetSelect(0, 32767, w->crt_TEH);
  66.         ZeroScrap();
  67.         TECopy(w->crt_TEH);
  68.         }
  69.     ExitToShell();
  70.     }
  71.  
  72. int    ours(WindowPtr win)
  73.     {
  74.     if (win != NULL)
  75.         {
  76.         struct crt_win *tmp = crt_windows;
  77.         while (tmp < &crt_windows[sizeof(crt_windows)/sizeof(*crt_windows)])
  78.             {
  79.             if (tmp->crt_myWindow == win)
  80.                 {
  81.                 w = tmp;
  82.                 return 1;
  83.                 }
  84.             ++tmp;
  85.             }
  86.         }
  87.     return 0;
  88.     }
  89.  
  90. int SetUpWindows(Str255 name, int winidx)
  91. {
  92.     Rect        viewRect;
  93.     FontInfo    myInfo;
  94.     GrafPort    myPort;
  95.  
  96.     w = &crt_windows[winidx];
  97.     OpenPort(&myPort);
  98.     SetPort(&myPort);
  99.     
  100.     TextFont(monaco);
  101.     TextSize(9);
  102.     GetFontInfo(&myInfo);
  103.     ClosePort(&myPort);
  104.  
  105.     viewRect.left = 0;
  106.     viewRect.top = 32;
  107.     viewRect.right = viewRect.left+82*myInfo.widMax+SBarWidth;
  108.     viewRect.bottom = viewRect.top+26*(myInfo.ascent+myInfo.descent+myInfo.leading)+SBarWidth;
  109.     OffsetRect(&viewRect,
  110.             (qd.screenBits.bounds.right-viewRect.right)/2+(winidx<<5),
  111.             (qd.screenBits.bounds.bottom-viewRect.bottom)/2+(winidx<<5));
  112.     w->crt_myWindow = NewWindow(&(w->crt_wRecord),&viewRect,name,1,0,(WindowPtr) -1L,1,0);
  113.     SetPort(w->crt_myWindow);
  114.     TextFont(monaco);
  115.     TextSize(9);
  116.     
  117.     viewRect = qd.thePort->portRect;
  118.     viewRect.left = viewRect.right-15;
  119.     viewRect.right += 1;
  120.     viewRect.bottom -= 14;
  121.     viewRect.top -= 1;
  122.     w->vScroll = NewControl( w->crt_myWindow, &viewRect, (unsigned char *)"\000", 1, 0, 0, 0, scrollBarProc, 0L);
  123.     
  124.     viewRect = qd.thePort->portRect;
  125.     viewRect.right -= SBarWidth;
  126.     viewRect.bottom -= SBarWidth;
  127.     InsetRect(&viewRect, 4, 4);
  128.  
  129.     w->crt_TEH = TEStylNew(&viewRect, &viewRect);
  130.     (**w->crt_TEH).viewRect = qd.thePort->portRect;
  131.     (**w->crt_TEH).viewRect.right -= SBarWidth;
  132.     (**w->crt_TEH).viewRect.bottom -= SBarWidth;
  133.     InsetRect(&(**w->crt_TEH).viewRect, 4, 4);
  134.  
  135.     w->linesInFolder = ((**w->crt_TEH).viewRect.bottom-(**w->crt_TEH).viewRect.top)/(**w->crt_TEH).lineHeight;
  136.     (**w->crt_TEH).viewRect.bottom = (**w->crt_TEH).viewRect.top + (**w->crt_TEH).lineHeight*w->linesInFolder;
  137.     (**w->crt_TEH).destRect.right = (**w->crt_TEH).viewRect.right;
  138.     TECalText(w->crt_TEH);
  139. }
  140.  
  141. int AdjustText (void)
  142.  
  143. {
  144.     int        oldScroll, newScroll, delta;
  145.     
  146.     oldScroll = (**w->crt_TEH).viewRect.top - (**w->crt_TEH).destRect.top;
  147.     newScroll = GetCtlValue(w->vScroll) * (**w->crt_TEH).lineHeight;
  148.     delta = oldScroll - newScroll;
  149.     if (delta != 0)
  150.       TEScroll(0, delta, w->crt_TEH);
  151. }
  152.  
  153. #ifdef SCROLLPROC
  154.  
  155. pascal void ScrollProc (ControlHandle theControl, int theCode)
  156. {
  157.     int    pageSize;
  158.     int    scrollAmt;
  159.     int oldCtl;
  160.     
  161.     if (theCode == 0)
  162.         return ;
  163.     
  164.     pageSize = ((**w->crt_TEH).viewRect.bottom-(**w->crt_TEH).viewRect.top) / 
  165.             (**w->crt_TEH).lineHeight - 1;
  166.             
  167.     switch (theCode) {
  168.         case inUpButton: 
  169.             scrollAmt = -1;
  170.             break;
  171.         case inDownButton: 
  172.             scrollAmt = 1;
  173.             break;
  174.         case inPageUp: 
  175.             scrollAmt = -pageSize;
  176.             break;
  177.         case inPageDown: 
  178.             scrollAmt = pageSize;
  179.             break;
  180.     }
  181.  
  182.     oldCtl = GetCtlValue(theControl);
  183.     SetCtlValue(theControl, oldCtl+scrollAmt);
  184.  
  185.     AdjustText();
  186.  
  187. }
  188.  
  189. #endif
  190.  
  191. int DoMouseDown (int windowPart, WindowPtr whichWindow, EventRecord *myEvent)
  192.  
  193. {
  194.     switch (windowPart) {
  195.         case inGoAway:
  196.             if (ours(whichWindow))
  197.                 if (TrackGoAway(whichWindow, myEvent->where))
  198.                         {
  199.                         HideWindow(whichWindow);
  200.                         TESetSelect(0, (**w->crt_TEH).teLength, w->crt_TEH);
  201.                         TEDelete(w->crt_TEH);
  202.                             {
  203.                                 register int    n;
  204.                                 
  205.                                 n = (**w->crt_TEH).nLines-w->linesInFolder;
  206.                             
  207.                                 if ((**w->crt_TEH).teLength > 0 && (*((**w->crt_TEH).hText))[(**w->crt_TEH).teLength-1]=='\r')
  208.                                     n++;
  209.                             
  210.                                 SetCtlMax(w->vScroll, n > 0 ? n : 0);
  211.                             }
  212.                         }
  213.             break;
  214.  
  215.         case inMenuBar:
  216.             return(HandleMenu(MenuSelect(myEvent->where)));
  217.  
  218.         case inSysWindow:
  219.             SystemClick(myEvent, whichWindow);
  220.             break;
  221.  
  222.         case inDrag:
  223.             if (ours(whichWindow))
  224.                 {
  225.                 Rect dragRect = { 0, 0, 1024, 1024 };
  226.                 DragWindow(whichWindow, myEvent->where, &dragRect);
  227.                 }
  228.             break;
  229.  
  230.         case inGrow:
  231.             if (ours(whichWindow))
  232.                 {
  233.                     Point p = myEvent->where;
  234.                     GrafPtr    savePort;
  235.                     long    theResult;
  236.                     Rect    oldHorizBar;
  237.                     Rect     r;
  238.                     
  239.                     GetPort(&savePort);
  240.                     SetPort(whichWindow);
  241.                     
  242.                     oldHorizBar = whichWindow->portRect;
  243.                     oldHorizBar.top = oldHorizBar.bottom - (SBarWidth+1);
  244.                 
  245.                     SetRect(&r, 80, 80, qd.screenBits.bounds.right, qd.screenBits.bounds.bottom);
  246.                     theResult = GrowWindow(whichWindow, p, &r);
  247.                     if (theResult == 0)
  248.                       return;
  249.                     SizeWindow( whichWindow, LoWord(theResult), HiWord(theResult), false);
  250.                 
  251.                     InvalRect(&whichWindow->portRect);
  252.                     
  253.                     (**w->crt_TEH).viewRect = whichWindow->portRect;
  254.                     (**w->crt_TEH).viewRect.right -= SBarWidth;
  255.                     (**w->crt_TEH).viewRect.bottom -= SBarWidth;
  256.                     InsetRect(&(**w->crt_TEH).viewRect, 4, 4);
  257.                 
  258.                     w->linesInFolder = ((**w->crt_TEH).viewRect.bottom-(**w->crt_TEH).viewRect.top)/(**w->crt_TEH).lineHeight;
  259.                     (**w->crt_TEH).viewRect.bottom = (**w->crt_TEH).viewRect.top + (**w->crt_TEH).lineHeight*w->linesInFolder;
  260.                     (**w->crt_TEH).destRect.right = (**w->crt_TEH).viewRect.right;
  261.                     TECalText(w->crt_TEH);
  262.  
  263.                     EraseRect(&oldHorizBar);
  264.                     
  265.                     MoveControl(w->vScroll, whichWindow->portRect.right - SBarWidth, whichWindow->portRect.top-1);
  266.                     SizeControl(w->vScroll, SBarWidth+1, whichWindow->portRect.bottom - whichWindow->portRect.top-(SBarWidth-2));
  267.                     r = (**w->vScroll).contrlRect;
  268.                     ValidRect(&r);
  269.                 
  270.                 
  271.                         {
  272.                             register int    n;
  273.                             
  274.                             n = (**w->crt_TEH).nLines-w->linesInFolder;
  275.                         
  276.                             if ((**w->crt_TEH).teLength > 0 && (*((**w->crt_TEH).hText))[(**w->crt_TEH).teLength-1]=='\r')
  277.                                 n++;
  278.                         
  279.                             SetCtlMax(w->vScroll, n > 0 ? n : 0);
  280.                         }
  281.  
  282.                     AdjustText();
  283.                     
  284.                     SetPort(savePort);
  285.                 }
  286.             break;
  287.  
  288.         case inContent:
  289.             if (whichWindow != FrontWindow())
  290.                 SelectWindow(whichWindow);
  291.             else if (ours(whichWindow))
  292.                 {
  293.                 int                cntlCode;
  294.                 ControlHandle     theControl;
  295.                 int                pageSize;
  296.                 GrafPtr            savePort;
  297.                 
  298.                 GetPort(&savePort);
  299.                 SetPort(whichWindow);
  300.                 
  301.                 GlobalToLocal(&myEvent->where);
  302.                 if ((cntlCode = FindControl(myEvent->where, whichWindow, &theControl)) == 0) {
  303.                 if (PtInRect(myEvent->where, &(**w->crt_TEH).viewRect))
  304.                     TEClick(myEvent->where, (myEvent->modifiers & shiftKey)!=0, w->crt_TEH);
  305.                 } else if (cntlCode == inThumb) {
  306.                 TrackControl(theControl, myEvent->where, 0L);
  307.                 AdjustText();
  308.                 } else
  309.                 TrackControl(theControl, myEvent->where, 
  310. #ifdef SCROLLPROC                
  311. &ScrollProc);
  312. #else
  313. 0);
  314. #endif
  315.                 SetPort(savePort);
  316.                 }
  317.             break;
  318.     }
  319. }
  320.  
  321.  
  322. int ShowSelect (void)
  323.  
  324. {
  325.     register    int        topLine, bottomLine, theLine;
  326.     
  327.     register int    n;
  328.     
  329.     n = (**w->crt_TEH).nLines-w->linesInFolder;
  330.  
  331.     if ((**w->crt_TEH).teLength > 0 && (*((**w->crt_TEH).hText))[(**w->crt_TEH).teLength-1]=='\r')
  332.         n++;
  333.  
  334.     SetCtlMax(w->vScroll, n > 0 ? n : 0);
  335.     AdjustText();
  336.     
  337.     topLine = GetCtlValue(w->vScroll);
  338.     bottomLine = topLine + w->linesInFolder;
  339.     
  340.     if ((**w->crt_TEH).selStart < (**w->crt_TEH).lineStarts[topLine] ||
  341.             (**w->crt_TEH).selStart >= (**w->crt_TEH).lineStarts[bottomLine]) {
  342.         for (theLine = 0; (**w->crt_TEH).selStart >= (**w->crt_TEH).lineStarts[theLine]; theLine++)
  343.             ;
  344.         SetCtlValue(w->vScroll, theLine - w->linesInFolder / 2);
  345.         AdjustText();
  346.     }
  347. }
  348.  
  349. int MaintainCursor(void)
  350. {
  351.     Point        pt;
  352.     WindowPeek    wPtr;
  353.     GrafPtr        savePort;
  354.     
  355.     if (ours((WindowPtr)(wPtr=(WindowPeek)FrontWindow()))) {
  356.         GetPort(&savePort);
  357.         SetPort((GrafPtr)wPtr);
  358.         GetMouse(&pt);
  359.         if (PtInRect(pt, &(**w->crt_TEH).viewRect ) )
  360.             SetCursor( *GetCursor(1));
  361.         else SetCursor(&qd.arrow);
  362.         SetPort(savePort);
  363.     }
  364. }
  365.  
  366. void test_inited(int minor)
  367.     {
  368. #if 0    
  369.     if (!qd.thePort)
  370.         {
  371.         InitGraf(&qd.thePort);
  372.         InitFonts();
  373.         InitWindows();
  374.         InitMenus();
  375.         TEInit();
  376.         InitCursor();
  377.         SetUpMenus();
  378.         }
  379. #endif
  380.     w = &crt_windows[minor];
  381.     if (!w->crt_myWindow)
  382.         {
  383.         Str255 name;
  384.         if (minor)
  385.             {
  386.             ksprintf((char *)name+1, "Window %d", minor);
  387.             *name = strlen(name+1);
  388.             }
  389.         else strcpy(name, "\pMessages");
  390.         SetUpWindows(name, minor);
  391.         }
  392.     }
  393.  
  394. int cwrite(int fd, const void *buf, int size)
  395.     {
  396.     char *ptr;
  397.     int lastcr,tot,cnt = 0;
  398.     Ptr newtext = NewPtr(size);
  399.     BlockMove(buf, newtext, size);
  400.     tot = size;
  401.     while (tot--)
  402.         {
  403.         if (newtext[tot]=='\n') newtext[tot]='\r';
  404.         }
  405.     if (fd!=-1) test_inited(fd);
  406.     TESetSelect(32767,32767,w->crt_TEH);
  407.     TEInsert(newtext, size, w->crt_TEH);
  408.     DisposPtr(newtext);
  409.     tot = (*w->crt_TEH)->teLength;
  410.     ptr = *((*w->crt_TEH)->hText);
  411.     lastcr = tot;
  412.     while (tot-- && (cnt < 24))
  413.         {
  414.         if (ptr[tot]=='\r')
  415.             {
  416.             cnt += (lastcr-tot)/80;
  417.             lastcr = tot;
  418.             cnt++;
  419.             }
  420.         }
  421.     if (tot > 0)
  422.         {
  423.         TESetSelect(0, tot, w->crt_TEH);
  424.         TEDelete(w->crt_TEH);
  425.         }
  426.     tot = (*w->crt_TEH)->teLength;
  427.     ptr = *((*w->crt_TEH)->hText);
  428.     lastcr = 0;
  429.     for (cnt = 0; cnt < tot; cnt++)
  430.         {
  431.         if (ptr[cnt]=='\r') lastcr = cnt;
  432.         if (ptr[cnt]=='\t')
  433.             {
  434.             int pos = (cnt-lastcr-1)&7;
  435.             int ins = 8-pos;
  436.             TESetSelect(cnt, cnt+1, w->crt_TEH);
  437.             TEDelete(w->crt_TEH);
  438.             TEInsert("        ", ins, w->crt_TEH);
  439.             ptr = *((*w->crt_TEH)->hText);
  440.             tot += ins-1;
  441.             }
  442.         }
  443.     TESetSelect(32767,32767,w->crt_TEH);
  444.     return size;
  445.     }
  446.  
  447. void checkevents(void) 
  448.         {
  449.         EventRecord        myEvent;
  450.         WindowPtr        whichWindow;
  451.         short            windowPart;
  452.         Rect            r;
  453.         MaintainCursor();
  454.         SystemTask();
  455.         if (w) TEIdle(w->crt_TEH);
  456.         if (GetNextEvent(everyEvent, &myEvent)) 
  457.             {
  458.             switch (myEvent.what) 
  459.                 {
  460.                 case mouseDown:
  461.                     windowPart = FindWindow(myEvent.where, &whichWindow);
  462.                     DoMouseDown(windowPart, whichWindow, &myEvent);
  463.                     break;
  464.                 case keyDown:
  465.                 case autoKey: 
  466.                     {
  467.                     unsigned char theChar;
  468.                     theChar = myEvent.message & charCodeMask;
  469.                     if ((myEvent.modifiers & cmdKey) != 0) 
  470.                         HandleMenu(MenuKey(theChar));
  471.                     else if (theChar < ' ')
  472.                         {
  473.                         TEKey(theChar, w->crt_TEH);
  474.                         if ((theChar == 3) || (theChar == 28)) interrupt = theChar;
  475.                          if (theChar == 4) theChar = -1; /* EOF */
  476.                          if (theChar == '\r') theChar = '\n';
  477.                          if (theChar == '\b') theChar = 127;
  478.                          if ((theChar == -1) || (theChar == '\n') || (theChar == 127))
  479.                              {
  480.                              write_console_stream(theChar);
  481.                             }
  482.                         }
  483.                     else
  484.                         {
  485.                         write_console_stream(theChar);
  486.                         if (w) cwrite(-1, &theChar, 1);                        
  487.                         }
  488.                     break;
  489.                     }    
  490.                 case activateEvt:
  491.                     if (ours((WindowPtr)myEvent.message)) 
  492.                         {
  493.                         if (myEvent.modifiers & activeFlag) 
  494.                             {
  495.                             TEActivate(w->crt_TEH);
  496.                             ShowControl(w->vScroll);
  497.                             }
  498.                         else 
  499.                             {
  500.                             TEDeactivate(w->crt_TEH);
  501.                             HideControl(w->vScroll);
  502.                             }
  503.                         }
  504.                     break;
  505.         
  506.                 case updateEvt:
  507.                     {
  508.                     WindowPtr myWindow = (WindowPtr) myEvent.message;
  509.                     if (ours(myWindow))
  510.                             {
  511.                                 GrafPtr    savePort;
  512.                                 
  513.                                 GetPort(&savePort);
  514.                                 SetPort(myWindow);
  515.                             
  516.                                 BeginUpdate(myWindow);
  517.                                 EraseRect(&myWindow->portRect);
  518.                                 DrawControls(myWindow);
  519.                                 DrawGrowIcon(myWindow);
  520.                                 TEUpdate(&myWindow->portRect, w->crt_TEH);
  521.                                 EndUpdate(myWindow);
  522.                             
  523.                                 SetPort(savePort);
  524.                             }                            
  525.                     break;
  526.                     }
  527.                 case kHighLevelEvent:
  528.                     AEProcessAppleEvent (&myEvent);
  529.                     break;
  530.                 } /* end of case myEvent.what */
  531.             } /* if */
  532.         }
  533.  
  534. long read_console_stream(int fd, char *readbuffer, long size)
  535.     {
  536.     long actual = 0;
  537.     tty_struct *buf;
  538.     if (!crt_windows[fd].console)
  539.         crt_windows[fd].console = (tty_struct *)xmalloc(sizeof(tty_struct));
  540.     buf = crt_windows[fd].console;
  541.     if (buf->complete_line)
  542.         {
  543.         checkevents();
  544.         while ((actual < size) && (buf->writeptr != buf->readptr))
  545.             {
  546.             int ch = buf->buffer[buf->readptr];
  547.             buf->readptr = (buf->readptr+1)&8191;
  548.             switch(ch)
  549.                 {
  550.                 case EOF: return EOF; break;
  551.                 case '\177': 
  552.                     if (actual >0) actual--; break;
  553.                 default: 
  554.                     readbuffer[actual++] = ch;
  555.                     break;
  556.                 }
  557.             }
  558.         buf->complete_line = 0;
  559.         return actual;
  560.         }
  561.     return 0;
  562.     }
  563.  
  564. int write_console_stream(int writechar)
  565.     {
  566.     long actual = 0;
  567.     tty_struct *buf;
  568.     if (!w->console) w->console = (tty_struct *)xmalloc(sizeof(tty_struct));
  569.     buf = w->console;
  570.     if (buf->writeptr != (buf->readptr-1)&8191)
  571.         {
  572.         buf->buffer[buf->writeptr] = writechar;
  573.         buf->writeptr = (buf->writeptr+1)&8191;
  574.         if (writechar == '\n') buf->complete_line = 1;
  575.         ++actual;
  576.         }
  577.     return actual;
  578.     }
  579.